package com.adjaisd.scarecrow.service.impl;

import com.adjaisd.scarecrow.dto.DeviceStatusDTO;
import com.adjaisd.scarecrow.dto.QuotaInfo;
import com.adjaisd.scarecrow.entity.Device;
import com.adjaisd.scarecrow.entity.DeviceStatus;
import com.adjaisd.scarecrow.mapper.DeviceStatusMapper;
import com.adjaisd.scarecrow.service.DeviceService;
import com.adjaisd.scarecrow.service.DeviceStatusService;
import com.adjaisd.scarecrow.service.QuotaService;
import com.adjaisd.scarecrow.vo.DeviceQuotaAlarmVO;
import com.adjaisd.scarecrow.vo.DeviceStatusVO;
import com.adjaisd.scarecrow.vo.Pager;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author adjaisd
 * @since 2022-03-27
 */
@Service
public class DeviceStatusServiceImpl extends ServiceImpl<DeviceStatusMapper, DeviceStatus> implements DeviceStatusService {

    @Autowired
    DeviceStatusMapper deviceStatusMapper;

    private DeviceStatus findDevice(Long deviceId) {
        QueryWrapper<DeviceStatus> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(DeviceStatus::getId, deviceId);
        List<DeviceStatus> list = this.list(wrapper);
        if (list.size() == 0) return null;
        return list.get(0);
    }

    @Override
    public DeviceStatus getDeviceStatusByID(Long deviceId) {
        return deviceStatusMapper.selectById(deviceId);
    }

    @Override
    public boolean setStatus(Long deviceId, Boolean status) {
        DeviceStatus deviceStatus = getDeviceStatusByID(deviceId);
        deviceStatus.setStatus(status);
        return this.updateById(deviceStatus);
    }

    @Override
    public boolean updateTag(Long deviceId, String tag) {
        DeviceStatus deviceStatus = getDeviceStatusByID(deviceId);
        deviceStatus.setTag(tag);
        return this.updateById(deviceStatus);
    }

    @Override
    public boolean addDeviceStatus(DeviceStatus deviceStatus) {
        DeviceStatus status = getDeviceStatusByID(deviceStatus.getId());
        if (status == null) return deviceStatusMapper.insert(deviceStatus) > 0;
        else return deviceStatusMapper.updateById(deviceStatus) > 0;
    }

    @Override
    public boolean saveDeviceInfo(DeviceStatusDTO deviceStatusDTO) {
        //查询设备 ，判断开关状态 ，如果是关闭则不处理
        DeviceStatus deviceStatus = findDevice(deviceStatusDTO.getDeviceId());
        if (deviceStatus != null && !deviceStatus.getStatus()) return false;

        DeviceStatus status = new DeviceStatus();
        BeanUtils.copyProperties(deviceStatusDTO, status);
        status.setId(deviceStatusDTO.getDeviceId());

        System.out.println("处理DeviceStatus=" + status);
        if (deviceStatus == null) return deviceStatusMapper.insert(status) > 0;
        else return deviceStatusMapper.updateById(status) > 0;
    }

    @Override
    public void updateOnLineByID(Long deviceId, boolean online) {
        DeviceStatus status = getDeviceStatusByID(deviceId);
        if (status == null) {
            DeviceStatus deviceStatus = new DeviceStatus(deviceId, false, null, 0, online, null, true);
            addDeviceStatus(deviceStatus);
        } else {
            status.setOnline(online);
            deviceStatusMapper.updateById(status);
        }
    }

    @Deprecated
    @Override
    public Pager<DeviceStatusVO> queryPage(long userId, long page, long pageSize, String number, String tag, int state) {
        String deviceId = "";
        if (!Strings.isNullOrEmpty(number)) {
            Device device = deviceService.getDeviceByNumber(Long.valueOf(number));
            deviceId = device.getId() + "";
        }
        Page<DeviceStatusVO> deviceStatusPage = searchDevice(userId, page, pageSize, deviceId, tag, state);
        return new Pager<>(deviceStatusPage);
    }

    @Autowired
    DeviceService deviceService;

    @Autowired
    QuotaService quotaService;

    @Override
    public Pager<DeviceQuotaAlarmVO> queryDeviceQuotaAlarm(Long userId, Long page, Long pageSize, String number, String tag, Integer state) {
        String deviceId = "";
        if (!number.equals("")) {
            Device device = deviceService.getDeviceByNumber(Long.valueOf(number));
            deviceId = device.getId() + "";
        }
        //1.查询设备状态列表
        Page<DeviceStatusVO> pager = searchDevice(userId, page, pageSize, deviceId, tag, state);

        //2.查询指标列表
        List<DeviceQuotaAlarmVO> deviceQuotaAlarmVOList = Lists.newArrayList();
        pager.getRecords().forEach(deviceStatus -> {
            DeviceQuotaAlarmVO deviceQuotaAlarmVO = new DeviceQuotaAlarmVO();
            BeanUtils.copyProperties(deviceStatus, deviceQuotaAlarmVO);
            deviceQuotaAlarmVO.setDeviceId(deviceStatus.getId() + "");
            //查询指标
            List<QuotaInfo> quotaList = quotaService.getLastQuotaList(deviceStatus.getId());
            deviceQuotaAlarmVO.setQuotaList(quotaList);
            deviceQuotaAlarmVOList.add(deviceQuotaAlarmVO);
        });

        //3.封装返回结果
        Pager<DeviceQuotaAlarmVO> pageResult = new Pager<>(pager.getTotal(), pageSize);
        pageResult.setPage(pager.getCurrent());
        pageResult.setItems(deviceQuotaAlarmVOList);

        return pageResult;
    }

    private Page<DeviceStatusVO> searchDevice(Long userId, Long page, Long pageSize, String deviceId, String tag, Integer state) {
        QueryWrapper<DeviceStatus> wrapper = new QueryWrapper<>();
        if (!Strings.isNullOrEmpty(deviceId)) {// 设备ID存在
            wrapper.lambda().eq(DeviceStatus::getId, Long.parseLong(deviceId));
        } else {
            // 根据用户ID获取设备列表
            List<Device> deviceListByUID = deviceService.getDeviceListByUID(userId);
            List<Long> deviceIdList = deviceListByUID.stream().map(Device::getId).collect(Collectors.toList());
            wrapper.lambda().in(DeviceStatus::getId, deviceIdList);
        }

        if (!Strings.isNullOrEmpty(tag)) {   // 标签存在
            LinkedList<String> tagList = new LinkedList<>();
            if (tag.contains(",")) tagList.addAll(Arrays.stream(tag.split(",")).collect(Collectors.toList()));
            else tagList.add(tag);
            for (String s : tagList)
                wrapper.lambda().like(DeviceStatus::getTag, s);
//            wrapper.lambda().in(DeviceStatus::getTag, tagList);
        }

        if (state > -1) {   // 设备状态存在
            if (state == 0) //在线
                wrapper.lambda().eq(DeviceStatus::getStatus, true)
                        .eq(DeviceStatus::getOnline, true);
            if (state == 1) //离线(离线或关闭)
                wrapper.lambda().eq(DeviceStatus::getStatus, false)
                        .or().eq(DeviceStatus::getOnline, false);
            if (state == 2) //一般报警：报警等级 1,2,3,4
                wrapper.lambda().gt(DeviceStatus::getAlarmLevel, 0)
                        .lt(DeviceStatus::getAlarm, 5);
            if (state == 3) //严重报警：报警等级 5,6,7,8
                wrapper.lambda().gt(DeviceStatus::getAlarmLevel, 4)
                        .lt(DeviceStatus::getAlarm, 9);
        }
        Page<DeviceStatus> deviceStatusPage = new Page<>(page, pageSize);
        Page<DeviceStatus> statusPage = this.page(deviceStatusPage, wrapper);

        // 找到对应状态的设备信息封装成DeviceStatusVO对象
        List<DeviceStatusVO> linkedList = new LinkedList<>();
        for (DeviceStatus deviceStatus : statusPage.getRecords()) {
            DeviceStatusVO deviceStatusVO = new DeviceStatusVO();
            BeanUtils.copyProperties(deviceStatus,deviceStatusVO);
            Device device = deviceService.getDeviceByID(deviceStatus.getId());
            BeanUtils.copyProperties(device,deviceStatusVO);
            linkedList.add(deviceStatusVO);
        }

        Page<DeviceStatusVO> pageResult = new Page<>(page, pageSize);
        BeanUtils.copyProperties(statusPage, pageResult);
        pageResult.setRecords(linkedList);
        return pageResult;
    }

}
